package com.fingard.dsp.bank.directbank.glb01;

import com.fingard.FGBiz;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author Alon on 2019-11-18.
 * @version 1.0
 */
public class GLB01BatPayRec extends GLB01Base implements IBatPayRec {
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,REQSEQID,BANKREQSEQID) values (?,?,?,?);";
    private static final String SELECTRECEIPT = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? and BANKCODE=?;";

    //批量代付
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        XmlTextWriter xmlWriter = new XmlTextWriter();//发送给银行的报文
        Connection conn = FGBiz.getLocalDbConn();

        try {
            GLB01Header glb01Header = new GLB01Header();
            glb01Header.serviceId = "CBE070710";
            glb01Header.serialNo = p_req1988.reqHeader.transSeqID;//这个作为银行交易流水号
            glb01Header.reqTime = p_req1988.reqHeader.transTime.replaceAll(" ", "").replaceAll("-", "").replaceAll(":", "");
            writeCommonHeader(xmlWriter, glb01Header);

            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("payAccount", p_req1988.ownAct);//付款账号
            xmlWriter.writeElementString("payMonth", "");//代发月份???
            xmlWriter.writeElementString("companyId", "");//代发工资编号???
            xmlWriter.writeElementString("totalAmount", p_req1988.totalAmt);//总金额
            xmlWriter.writeElementString("totalNumber", p_req1988.totalNum);//总笔数
            xmlWriter.writeElementString("showDetail", "1");//总笔数
            xmlWriter.writeStartElement("list");

            while (p_req1988.readRecord()) {
                xmlWriter.writeStartElement("row");
                xmlWriter.writeElementString("recAccount", p_req1988.readedDetail.recAct);//收款账号
                xmlWriter.writeElementString("recAccountName", p_req1988.readedDetail.recName);//收款账户名
                xmlWriter.writeElementString("payAmount", p_req1988.readedDetail.payAmount);//付款金额
                xmlWriter.writeElementString("payRem", p_req1988.readedDetail.purpose);//付款备注(ATS将用途写在备注)
                xmlWriter.writeElementString("employeeId", p_req1988.readedDetail.askNumber);//员工号???(在员工号里写一个批次里面单笔的流水号)
                xmlWriter.writeEndElement();//row
            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/ebank/head/retCode");
                    String returnMsg = tmpBkReader.getFirstText("/ebank/head/retMessage");
                    if (returnCode != null && "000000".equals(returnCode)) {
                        retAts.respCode = "0";
                        String status = tmpBkReader.getFirstText("/ebank/body/status");
                        //90：提交成功
                        //99：提交失败
                        if ("90".equals(status)) {
                            String batchNo = tmpBkReader.getFirstText("/ebank/body/batchNo");
                            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                            JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{uuid, p_req1988.reqHeader.bankCode, p_req1988.reqBatchNO, batchNo});
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            //90的时候returnMsg为空
                            retAts.respInfo = "交易已经提交，交易结果待查询";
                            retAts.transState = returnCode + "+" + status;
                            retAts.payInfoCode = retAts.transState;
                        } else {
                            retAts.reqSeqID = p_req1988.reqBatchNO;
                            retAts.respInfo = returnMsg;
                            retAts.transState = returnCode + "+" + status;
                            retAts.payInfoCode = retAts.transState;
                        }
                    } else {
                        retAts.respCode = "0";
                        retAts.reqSeqID = p_req1988.reqBatchNO;
                        retAts.respInfo = returnMsg;
                        retAts.transState = returnCode;
                        retAts.payInfoCode = retAts.transState;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn(e);
        } finally {
            conn.close();
        }
        retAts.writeRetToATS();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {

            /**
             * 分页循环，发送报文
             */
            int tmpNowReadStart = 1;//起始页数
            int tmpNowReadNum = 0;//已查询笔数
            Map<String, Integer> tmpTotalNum = new HashMap<String, Integer>();
            while (tmpNowReadNum == 0 || tmpNowReadNum < tmpTotalNum.get("totalCount")) {
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                GLB01Header glb01Header = new GLB01Header();
                glb01Header.serviceId = "CBE070711";
                glb01Header.serialNo = p_req1998.reqHeader.transSeqID;//这个作为银行交易流水号
                glb01Header.reqTime = p_req1998.reqHeader.transTime.replaceAll(" ", "").replaceAll("-", "").replaceAll(":", "");
                writeCommonHeader(xmlWriter, glb01Header);

                Map<String, Object> map = JDBCHelper.execQuerySingle(conn, SELECTRECEIPT, new Object[]{p_req1998.reqBatchNO, p_req1998.reqHeader.bankCode});
                if (map.size() == 0) {
                    retAts.respCode = "-1";
                    retAts.respInfo = "没有这条请求映射的交易批次号！";
                    retAts.writeAfterDetail();
                    return retAts;
                }
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("batchNo", map.get("BANKREQSEQID").toString());
                xmlWriter.writeElementString("turnPageBeginPos", tmpNowReadStart + "");
                xmlWriter.writeElementString("turnPageShowNum", "20");
                xmlWriter.writeEndElement();//body
                //签名
                int headBegin = xmlWriter.toXmlString().indexOf("<head>");
                int bodyEnd = xmlWriter.toXmlString().indexOf("</body>");
                String signData = xmlWriter.toXmlString().substring(headBegin, bodyEnd + 7);
                String signResult = sendHttpRequestToSign(signData);//对报文进行签名
                if (signResult != null && signResult.trim().length() > 0) {
                    int signBegin = signResult.indexOf("<sign>");
                    int signEnd = signResult.indexOf("</sign>");
                    String sign = signResult.substring(signBegin + 6, signEnd);
                    xmlWriter.writeElementString("sign", sign);
                    xmlWriter.writeEndDocument();
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "获取签名数据失败，请求报文发送失败";
                    retAts.writeAfterDetail();
                    return retAts;
                }

                String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());
                if (tmpRetBkStr[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String returnCode = tmpBkReader.getFirstText("/ebank/head/retCode");
                        String returnMsg = tmpBkReader.getFirstText("/ebank/head/retMessage");
                        if (returnCode != null && "000000".equals(returnCode)) {
                            //符合条件的条数，总明细数
                            String totalCount = tmpBkReader.getFirstText("/ebank/body/turnPageTotalNum");
                            if (tmpTotalNum.containsKey("totalCount")) {
                                if (!tmpTotalNum.get("totalCount").equals(Integer.valueOf(totalCount))) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "相同条件前后查出来的总数不一致";
                                    break;
                                }
                            } else {
                                if ("0".equals(totalCount)) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "查询页:" + tmpNowReadStart + ",总明细条数为0";
                                    break;
                                }
                                tmpTotalNum.put("totalCount", Integer.valueOf(totalCount));//记录总条数
                            }

                            retAts.respCode = "0";
                            retAts.respInfo = "查询批量支付状态操作成功！";
                            retAts.reqSeqID = p_req1998.reqBatchNO;
                            int readCount = 0;
                            while (tmpBkReader.read("/ebank/body/list/row")) {
                                XElement readXElement = tmpBkReader.readedXElement;
                                RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                tmpRetDetail.payAct = p_req1998.ownAct;//付方账号
                                tmpRetDetail.recAct = readXElement.getSingleText("recAccount");//收方账号
                                tmpRetDetail.curType = convertCurToATS(readXElement.getSingleText("currencyType"));//币种
                                tmpRetDetail.payAmount = readXElement.getSingleText("payAmount");//交易金额
                                tmpRetDetail.memo = readXElement.getSingleText("payRem");//备注
                                tmpRetDetail.postScript = readXElement.getSingleText("employeeId");//批次内每一笔的流水号(提交的时候在员工号里写入)
                                String orderState = readXElement.getSingleText("orderState");//交易状态
                                //指令状态（00：等待复核；01：复核被拒绝；02：录入后待授权；05：复核后待授权；10：等待授权（授权中）；
                                // 11：授权被拒绝；20：等待自动发送（中间状态，随后就被置为50）；21：等待手工发送；31：编辑中；
                                // 33：录入待授权；50：主机处理中；51：交易处理中（是指线程处理中）；56：等待后台处理（代发工资异步）；
                                // 57：终止（代发工资提交后台后撤销）；60：预约待处理（预约交易审核后待发主机）；61：预约被撤销；
                                // 70:落地处理中；71:落地拒绝；90：交易成功；91：交易被撤销（包括发送被撤销、录入待审核被撤销和审核被拒绝被撤销）；
                                // 92：交易作废；93：指令逾期作废；95：部分成功；99：交易失败）
                                tmpRetDetail.result = returnCode + "+" + orderState;
                                tmpRetDetail.payInfoCode = returnCode + "+" + orderState;
                                retAts.writeRetDetail(tmpRetDetail);
                                readCount++;
                            }
                            tmpNowReadNum += readCount;//已查询条数
                            if (Integer.parseInt(totalCount) > tmpNowReadNum) {
                                //总条数大于已查询条数，说明查询了默认条数的明细
                                if (readCount != Integer.valueOf(getBankConfig().getValueAsString("pageSize"))) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "总条数大于已查询条数,统计明细有误";
                                    break;
                                }
                            }
                            if (Integer.parseInt(totalCount) < tmpNowReadNum) {
                                //总条数小于已查询条数,说明数据异常
                                retAts.respCode = "-1";
                                retAts.respInfo = "总条数小于已查询条数,统计明细有误";
                                break;
                            }
                            tmpNowReadStart++;//查询起始页加1
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = returnMsg;
                            break;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpRetBkStr[1];
                    break;
                }
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        } finally {
            conn.close();
        }
        if ("-1".equals(retAts.respCode) && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1998.reqBatchNO;
        }
        if ("-1".equals(retAts.respCode)) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
